﻿using Microsoft.Extensions.DependencyInjection;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");

            // 构造容器对象 IServiceProvider
            ServiceCollection services = new ServiceCollection();

            services.AddTransient<TestServiceI, TestScopedServiceImpl>();

            services.AddTransient<TestServiceImpl>();
            services.AddScoped<TestScopedServiceImpl>();

            using (var serviceProvider = services.BuildServiceProvider())
            {
                TestServiceImpl testService = serviceProvider.GetRequiredService<TestServiceImpl>();
                testService.Name = "tom";
                testService.SayHi();

                TestServiceImpl testService1 = serviceProvider.GetRequiredService<TestServiceImpl>();
                Console.WriteLine(object.ReferenceEquals(testService, testService1)); // False

                // 使用有范围的服务对象
                using (var scope = serviceProvider.CreateScope())
                {
                    TestScopedServiceImpl testScopedService = serviceProvider.GetRequiredService<TestScopedServiceImpl>();

                    TestScopedServiceImpl testScopedService1 = serviceProvider.GetRequiredService<TestScopedServiceImpl>(); // 未注册，抛出异常

                    Console.WriteLine(object.ReferenceEquals(testScopedService, testScopedService1)); // True

                    TestServiceI testScopedService2 = serviceProvider.GetService<TestServiceI>(); // 未注册，返回null
                    testService.Name = "lily";
                    testService.SayHi();

                    Console.WriteLine(object.ReferenceEquals(testScopedService, testScopedService2)); // False
                }

                IEnumerable<TestServiceImpl> testServices = serviceProvider.GetServices<TestServiceImpl>(); // 注册多次
                Console.WriteLine(testServices.Count()); // 1

            }

            // DI会传染
            services.AddScoped<MyController>();
            services.AddScoped<MyLogI, MyLogImpl>();
            services.AddScoped<MyStorageI, MyStorageImpl>();
            services.AddScoped<MyConfigI, MyConfigImpl>();
            services.AddScoped<MyConfigI, MyDbConfigImpl>();

            using (var sp = services.BuildServiceProvider())
            {
                using(var scope = sp.CreateScope())
                {
                    var controller = scope.ServiceProvider.GetService<MyController>();
                    controller?.Test();
                }
            }

        }
    }
}
